package com.cyru.statemachine.core.impl;

import com.cyru.statemachine.Visitor;
import com.cyru.statemachine.core.State;
import com.cyru.statemachine.core.StateMachine;
import com.cyru.statemachine.core.Transition;
import org.springframework.util.CollectionUtils;
import java.util.Set;

/**
 * Created on 2021/8/4.
 *
 * @author zhang ling
 */
public class PlantUmlVisitor implements Visitor {
    private static final String START_UML = "@startuml";
    private static final String END_UML= "@enduml";

    @Override
    public String visitOnEntry(StateMachine<?, ?, ?> stateMachine) {
        if (stateMachine.getConfiguration() == null) {
            return START_UML;
        }
        Set<?> initStates = stateMachine.getConfiguration().getInitStates();
        StringBuilder sb = new StringBuilder();
        sb.append(START_UML).append(Visitor.newLine);
        if (CollectionUtils.isEmpty(initStates)){
            return sb.toString();
        }

        //初始节点
        initStates.forEach(s -> sb.append("[*] --> ").append(s));
        return sb.toString();

    }

    @Override
    public String visitState(State<?, ?, ?> state) {
        StringBuilder sb = new StringBuilder();
        for (Transition<?, ?, ?> transition : state.getAllTransition()) {
            sb.append(transition.getSourceState().getId())
                    .append(" --> ")
                    .append(transition.getTargetState().getId())
                    .append(" : ").append(transition.getTrigger().getEvent())
                    .append(Visitor.newLine);
        }
        return sb.toString();
    }

    @Override
    public String visitOnExsit(StateMachine<?, ?, ?> stateMachine) {
        if (stateMachine.getConfiguration() == null) {
            return END_UML;
        }
        Set<?> endStates= stateMachine.getConfiguration().getEndStates();
        if (CollectionUtils.isEmpty(endStates)) {
            return END_UML;
        }
        StringBuilder sb = new StringBuilder();
        endStates.forEach(s -> sb.append(s).append(" --> [*]").append(Visitor.newLine));
        sb.append(END_UML);
        return sb.toString();
    }
}
